/* 
 * This file part of cget - A libcurl based downloading tool.
 * http://lianwei3.googlepages.com/home2
 * Copyright (C) 2006 Wei Lian <lianwei3@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
#include "header.h"
#include "parseheader.h"
#include "downloader.h"
#include "filemanager.h"
#include "util.h"


char *file_name_consistency_check(std::vector
				  < struct ThreadInfo >*vec_info)
{
    std::string str[vec_info->size()];
    for (uint i = 0; i < vec_info->size(); i++) {
	str[i] = vec_info->at(i).url;
	std::string::size_type pos = str[i].rfind("/");
	str[i] = str[i].substr(pos + 1);
    }
    for (uint i = 1; i < vec_info->size(); i++) {
	if (str[i] != str[0]) {
	    printf("File names are inconsistent with each other!\n");
	    exit(1);
	}
    }
    ////get output file name
    char *outfile = new char[strlen(str[0].c_str()) + 1];
    strcpy(outfile, str[0].c_str());
    return outfile;
}




int main(int argc, char **argv)
{
    int c;
    char *outfile = NULL;
    ///parse cmdline
    while ((c = getopt(argc, argv, ":o:O:")) != -1) {
	switch (c) {
	case 'O':
	case 'o':
	    outfile = optarg;
	    break;
	default:
	  EXIT:
	    printf("Usage: cget url1 url2 ... [-O output_file]\n");
	    exit(1);
	}
    }
    int opt_num = 2;
    if (optind == 1) {		///no option
	opt_num = 0;
    }
    if (optind == argc) {	///no url list
	goto EXIT;
    }
    ////get url info
    std::vector < struct ThreadInfo >vec_info(argc - 1 - opt_num);
    for (int i = optind; i < argc; i++) {
	vec_info.at(i - optind).length = 0;
	vec_info.at(i - optind).url = argv[i];
	vec_info.at(i - optind).vecptr = &vec_info;
    }
    ///verify file name consistency
    char *tempfile = file_name_consistency_check(&vec_info);
    if (outfile)
	free(tempfile);
    else
	outfile = tempfile;
    assert(outfile);
    ///test file existence
    if (file_exist(outfile)) {
	printf("file already exist!\n");
	exit(0);
    }
    printf("waiting...\n");
    ///parse file header and get length
    pthread_t tid[argc - 1 - opt_num];
    for (int i = 0; i < argc - 1 - opt_num; i++) {
	vec_info.at(i).curl = curl_easy_init();
	vec_info.at(i).thread = &(tid[i]);
    }
    ParseHeader parseheader;
    parseheader.get_file_length(&vec_info);
    ///cleanup useful for redirect links
    for (int i = 0; i < argc - 1 - opt_num; i++) {
	curl_easy_cleanup(vec_info.at(i).curl);
	vec_info.at(i).curl = curl_easy_init();
    }
    ///temprary file for download
    char outfile_cg[strlen(outfile) + 5];
    strcpy(outfile_cg, outfile);
    strcat(outfile_cg, ".cg!");
    ///open file for downloading
    FileManager filemanager;
    filemanager.file_open(outfile, outfile_cg, &vec_info);
    ///dealing with added vector elements
    pthread_t tid2[vec_info.size() - (argc - 1 - opt_num)];
    for (int i = argc - 1 - opt_num; i < (int) vec_info.size(); i++) {
	vec_info.at(i).curl = curl_easy_init();
	vec_info.at(i).thread = &tid2[i - (argc - 1 - opt_num)];
    }
    ///download
    Downloader downloader;
    downloader.execute_download(&vec_info, argc - 1 - opt_num, outfile_cg);
    ////truncate to original length
    truncate(outfile_cg, vec_info.at(0).length);
    ////rename
    rename(outfile_cg, outfile);
    ///close ncurs
    return 0;
}
